package com.xbongbong.paas.script.controller;

import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.pojo.dto.FixSignInAddressDTO;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.helper.GaodeGeoHelper;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.pro.config.ProBaseConfig;
import com.xbongbong.pro.constant.XbbProConstant;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.SignInEntity;
import com.xbongbong.saas.model.SignInModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @Author: hongxiao
 * @date: 2020-11-13 16:39
 */
@RestController
@RequestMapping(XbbProConstant.API_ROOT_PREFIX+"/script/signIn")
public class SignInScriptController {
    private static final Logger LOG = LoggerFactory.getLogger(SignInScriptController.class);
    @Resource
    private ProBaseConfig proBaseConfig;

    @Resource
    private SignInModel signInModel;

    /**
     * 修改单个公司签到地址数据
     *
     * @param fixSignInAddressDTO 入参
     * @throws
     * @return
     * @author hongxiao
     * @date 2020-11-13 16:39
     * @since
     * @version
     */
    @RequestMapping(value = "/fixAddress", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String fixAddress(@RequestBody @Valid FixSignInAddressDTO fixSignInAddressDTO, BindingResult br) throws XbbException {
        if (!proBaseConfig.getXbbCode().equals(fixSignInAddressDTO.getXbbCode())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006);
        }
        List<String> corpidList = fixSignInAddressDTO.getCorpidList();
        if (CollectionsUtil.isEmpty(corpidList)) {
            // 刷所有公司的数据
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, "公司id不能为空");
        }

        // 调用高德api有次数限制，每次只刷一家公司
        long start = DateTimeUtil.getInt();
        String corpid = corpidList.get(0);

        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put(StringConstant.CORPID, corpid);
        param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
        param.put("address", "");
        Integer totalCount = signInModel.getEntitysCount(param);
        if (totalCount == 0) {
            LOG.warn("没有需要更新的数据");
            return "sucess";
        }

        LOG.warn("数据库中共有" + totalCount + "条无签到数据");

        int pageSize = 100;
        int totalPage = (totalCount % pageSize == 0) ? (totalCount / pageSize) : (totalCount / pageSize) + 1;
        int lastPageSize = (totalCount % pageSize == 0) ? pageSize : (totalCount % pageSize);
        int updateCount = 0;
        for (int page = 0; page < totalPage; page++) {
            if (page == totalPage - 1) {
                param.put("pageNum", lastPageSize);
            } else {
                param.put("pageNum", pageSize);
            }
            param.put("start", page * pageSize);
            List<SignInEntity> signInEntityDBList = signInModel.findEntities(param);
            if (signInEntityDBList.isEmpty()) {
                continue;
            }

            List<SignInEntity> updateList = new ArrayList<>();
            for (SignInEntity signInEntity : signInEntityDBList) {
                JSONObject addressObj = null;
                if (Objects.nonNull(signInEntity.getLongitude()) && Objects.nonNull(signInEntity.getLatitude())) {
                    try {
                        addressObj = GaodeGeoHelper.regeo(signInEntity.getLongitude(), signInEntity.getLatitude());
                    } catch (XbbException e) {
                        continue;
                    }
                }
                if (Objects.nonNull(addressObj)) {
                    SignInEntity updateEntity = new SignInEntity();
                    updateEntity.setId(signInEntity.getId());
                    updateEntity.setCorpid(signInEntity.getCorpid());
                    updateEntity.setAddress(addressObj.getString(PaasConstant.ADDRESS));
                    updateEntity.setProvince(addressObj.getString(PaasConstant.PROVINCE));
                    updateEntity.setCity(addressObj.getString(PaasConstant.CITY));
                    updateEntity.setDistrict(addressObj.getString(PaasConstant.DISTRICT));
                    updateList.add(updateEntity);
                }
            }

            if (!updateList.isEmpty()) {
                signInModel.updateBatch(updateList, corpid);
                updateCount += updateList.size();
                LOG.warn("批量修改签到地址数据：" + updateCount + "/" + totalCount);
            }
        }

        LOG.warn("consume:" + (DateTimeUtil.getInt() - start));
        LOG.warn("操作成功");

        return "success";
    }

    /**
     * 修复所有公司签到地址数据
     *
     * @param fixSignInAddressDTO 入参
     * @throws
     * @return
     * @author hongxiao
     * @date 2020-11-16 19:28
     * @since
     * @version
     */
    @RequestMapping(value = "/fixAllAddress", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String fixAllAddress(@RequestBody @Valid FixSignInAddressDTO fixSignInAddressDTO, BindingResult br) throws XbbException {
        if (!proBaseConfig.getXbbCode().equals(fixSignInAddressDTO.getXbbCode())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006);
        }

        // 调用高德api有次数限制，每次只刷一家公司
        long start = DateTimeUtil.getInt();

        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
        param.put("address", "");
        Integer totalCount = signInModel.getEntitysCount(param);
        if (totalCount == 0) {
            LOG.warn("没有需要更新的数据");
            return "sucess";
        }

        LOG.warn("数据库中共有" + totalCount + "条无签到数据");

        int pageSize = 100;
        int totalPage = (totalCount % pageSize == 0) ? (totalCount / pageSize) : (totalCount / pageSize) + 1;
        int lastPageSize = (totalCount % pageSize == 0) ? pageSize : (totalCount % pageSize);
        int updateCount = 0;
        for (int page = 0; page < totalPage; page++) {
            if (page == totalPage - 1) {
                param.put("pageNum", lastPageSize);
            } else {
                param.put("pageNum", pageSize);
            }
            param.put("start", page * pageSize);
            List<SignInEntity> signInEntityDBList = signInModel.findEntities(param);
            if (signInEntityDBList.isEmpty()) {
                continue;
            }

            List<SignInEntity> updateList = new ArrayList<>();
            for (SignInEntity signInEntity : signInEntityDBList) {
                JSONObject addressObj = null;
                if (Objects.nonNull(signInEntity.getLongitude()) && Objects.nonNull(signInEntity.getLatitude())) {
                    try {
                        addressObj = GaodeGeoHelper.regeo(signInEntity.getLongitude(), signInEntity.getLatitude());
                    } catch (XbbException e) {
                        continue;
                    }
                }
                if (Objects.nonNull(addressObj)) {
                    SignInEntity updateEntity = new SignInEntity();
                    updateEntity.setId(signInEntity.getId());
                    updateEntity.setCorpid(signInEntity.getCorpid());
                    updateEntity.setAddress(addressObj.getString(PaasConstant.ADDRESS));
                    updateEntity.setProvince(addressObj.getString(PaasConstant.PROVINCE));
                    updateEntity.setCity(addressObj.getString(PaasConstant.CITY));
                    updateEntity.setDistrict(addressObj.getString(PaasConstant.DISTRICT));
                    updateList.add(updateEntity);
                }
            }

            if (!updateList.isEmpty()) {
                signInModel.updateBatch(updateList, null);
                updateCount += updateList.size();
                LOG.warn("批量修改签到地址数据：" + updateCount + "/" + totalCount);
            }
        }

        LOG.warn("consume:" + (DateTimeUtil.getInt() - start));
        LOG.warn("操作成功");

        return "success";
    }

}
